package com.easylinkin.linkappapi.circuit.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easylinkin.linkappapi.circuit.dto.RailGiveAlarmTypeConfigDTO;
import com.easylinkin.linkappapi.circuit.dto.RailGiveAlarmTypeConfigEnum;
import com.easylinkin.linkappapi.circuit.entity.RailGiveAlarmTypeConfig;
import com.easylinkin.linkappapi.circuit.mapper.RailGiveAlarmTypeConfigMapper;
import com.easylinkin.linkappapi.circuit.service.IRailGiveAlarmTypeConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.circuit.vo.RailGiveAlarmTypeConfigVO;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lyk
 * @date 2025/6/17 下午 1:54
 */
@Service
@Slf4j
public class RailGiveAlarmTypeConfigServiceImpl  extends ServiceImpl<RailGiveAlarmTypeConfigMapper, RailGiveAlarmTypeConfig>  implements IRailGiveAlarmTypeConfigService {
    @Autowired
    private LinkappUserContextProducer linkappUserContextProducer;

    @Override
    public IPage<RailGiveAlarmTypeConfigVO> selectPage(Page page, RailGiveAlarmTypeConfigDTO customQueryParams) {
        customQueryParams.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.findPage(page,customQueryParams);
    }

    @Override
    public List<RailGiveAlarmTypeConfigVO> selectList(RailGiveAlarmTypeConfigDTO requestModel) {
        requestModel.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.findListByCondition(requestModel);
    }

    @Override
    public void addOrEditBatch(List<RailGiveAlarmTypeConfig> recordList) {
        log.info("Add Or Edit Batch RailGiveAlarmTypeConfig {}", JSON.toJSONString(recordList));
        Set<String> typeList = recordList.stream().map(RailGiveAlarmTypeConfig::getType).collect(Collectors.toSet());
        LambdaQueryWrapper<RailGiveAlarmTypeConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RailGiveAlarmTypeConfig::getType, typeList);
        queryWrapper.eq(RailGiveAlarmTypeConfig::getTenantId, linkappUserContextProducer.getNotNullCurrent().getTenantId());
        //先删除
        this.remove(queryWrapper);
        for (RailGiveAlarmTypeConfig railGiveAlarmTypeConfig : recordList) {
            railGiveAlarmTypeConfig.setId(null);
            setBase(railGiveAlarmTypeConfig);
            railGiveAlarmTypeConfig.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
            this.save(railGiveAlarmTypeConfig);
        }
    }

    /**
     * 设置基本属性
     *
     * @param equipmentLocation
     */
    private void setBase(RailGiveAlarmTypeConfig railGiveAlarmTypeConfig) {
        railGiveAlarmTypeConfig.setModifyTime(new Date());
        railGiveAlarmTypeConfig.setModifyId(linkappUserContextProducer.getCurrent().getId());
        //没有id就是新增,有就是编辑
        if (StringUtils.isBlank(railGiveAlarmTypeConfig.getId())) {
            railGiveAlarmTypeConfig.setCreateId(linkappUserContextProducer.getCurrent().getId());
            railGiveAlarmTypeConfig.setCreateTime(new Date());
            railGiveAlarmTypeConfig.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        }
    }

    /**
     * @param type
     */
    @Override
    public void initAllConfig(String tenantId) {
        if (StringUtils.isBlank(tenantId)) {
            return;
        }
        // 判断是否已经有了配置
        LambdaQueryWrapper<RailGiveAlarmTypeConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RailGiveAlarmTypeConfig::getTenantId, tenantId);
        int count = this.count(queryWrapper);
        if (count > 0) {
            return;
        }
        RailGiveAlarmTypeConfigEnum[] values = RailGiveAlarmTypeConfigEnum.values();
        for (RailGiveAlarmTypeConfigEnum e:values){
            RailGiveAlarmTypeConfig config = new RailGiveAlarmTypeConfig();
            config.setEnabled(0);
            config.setCategory(e.getCategory());
            config.setTenantId(tenantId);
            config.setType(e.getType());
            config.setText(e.getText());
            config.setFieids(e.getFields());
            baseMapper.insert(config);
        }
    }

    /**
     * 查询计划值
     * @param requestModel
     * @return
     */
    @Override
    public List<RailGiveAlarmTypeConfigVO> planValue(RailGiveAlarmTypeConfigDTO requestModel) {
        List<RailGiveAlarmTypeConfigVO> configVOS = selectList(requestModel);
        //去掉设备离线的，也就是 type = 7
        if (CollectionUtil.isNotEmpty(configVOS)){
            configVOS.removeIf(c->"7".equals(c.getType()));
            //再去掉没有设置阈值的
            configVOS.removeIf(c->Objects.isNull(c.getThreshValue()));
            // 按type分类，然后取等级最低的那一个（1级 < 2级 < 3级，数字越小等级越低）
            Map<String, List<RailGiveAlarmTypeConfigVO>> typeGroupMap = configVOS.stream()
                    .collect(Collectors.groupingBy(RailGiveAlarmTypeConfigVO::getType));

            List<RailGiveAlarmTypeConfigVO> result = new ArrayList<>();
            for (Map.Entry<String, List<RailGiveAlarmTypeConfigVO>> entry : typeGroupMap.entrySet()) {
                List<RailGiveAlarmTypeConfigVO> typeConfigs = entry.getValue();
                // 找到等级最低的配置（level值最小的）
                RailGiveAlarmTypeConfigVO lowestLevelConfig = typeConfigs.stream()
                        .min(Comparator.comparing(config -> {
                            String level = config.getLevel();
                            return level != null ? Integer.parseInt(level) : Integer.MAX_VALUE;
                        }))
                        .orElse(null);

                if (lowestLevelConfig != null) {
                    result.add(lowestLevelConfig);
                }
            }
            //排序 order by a.type, a.level 并返回
            return result.stream().sorted(Comparator.comparing(RailGiveAlarmTypeConfigVO::getType).thenComparing(RailGiveAlarmTypeConfigVO::getLevel)).collect(Collectors.toList());
        }

        return Collections.emptyList();
    }

}
